// SPDX-FileCopyrightText: Michael Popoloski
// SPDX-License-Identifier: MIT

#include "AnalysisTests.h"
#include "Test.h"
#include <fmt/core.h>

#include "slang/analysis/CaseDecisionDag.h"

using namespace slang::analysis;

static void testDag(const std::vector<std::string>& clauses, uint32_t bitWidth,
                    const flat_hash_set<uint32_t>& expectedUnreachable = {},
                    const std::optional<std::string>& expectedCounterexample = {},
                    const flat_hash_set<std::pair<uint32_t, uint32_t>>& expectedOverlaps = {},
                    bool wildcardX = false, bool expectGaveUp = false) {
    std::vector<SVInt> svClauses;
    for (const auto& clause : clauses)
        svClauses.emplace_back(SVInt::fromString(fmt::format("{}'b{}", bitWidth, clause)));

    std::optional<SVInt> svCounterexample;
    if (expectedCounterexample) {
        svCounterexample = SVInt::fromString(
            fmt::format("{}'b{}", bitWidth, *expectedCounterexample));
    }

    CaseDecisionDag dag(svClauses, bitWidth, wildcardX, 8192);

    CHECK(dag.gaveUp == expectGaveUp);
    if (dag.gaveUp)
        return;

    CHECK(dag.unreachableClauses == expectedUnreachable);
    CHECK(dag.overlappingClauses == expectedOverlaps);

    // This works around some kind of GCC miscompilation when trying
    // to use the normal std::optional operator==
    CHECK(dag.counterexample.has_value() == svCounterexample.has_value());
    if (svCounterexample)
        CHECK(*dag.counterexample == *svCounterexample);
}

TEST_CASE("Case Dag Exhaustiveness") {
    testDag({"1?", "00", "01"}, 2);
    testDag({"???"}, 3);
    testDag({"11?", "10?", "01?", "00?"}, 3);
}

TEST_CASE("Case Dag Non-exhaustive") {
    testDag({"11", "00"}, 2, {}, "01"); // Expects 01 because '0' branch is explored first
    testDag({"101"}, 3, {}, "000");     // Expects 000 first
    testDag({}, 3, {}, "000");
}

TEST_CASE("Case Dag Unreachable Clauses") {
    testDag({"1??", "11?", "0??"}, 3, {1});
    testDag({"11?", "1??", "0??"}, 3, {}, {}, {{0, 1}}); // Clause 1 is NOT redundant
    testDag({"???", "1??", "?0?", "111"}, 3, {1, 2, 3});
    testDag({"10", "01"}, 2, {}, "0");
}

TEST_CASE("Case Dag Overlapping Clauses") {
    testDag({"1??", "?1?"}, 3, {}, "0", {{0, 1}});         // Overlap on 11?
    testDag({"1??", "11?", "?1?"}, 3, {1}, "0", {{0, 2}}); // 1 is redundant, 0 overlaps 2 (on 11?)
    testDag({"10?", "01?"}, 3, {}, "000", {});
}

TEST_CASE("Case Dag Empty Cases") {
    testDag({}, 1, {}, "0");
    testDag({"0"}, 1, {}, "1");
    testDag({"1"}, 1, {}, "0");
}

TEST_CASE("Case Dag Large List 1") {
    testDag({"1???????????????????????????????????????????????????????????????",
             "01??????????????????????????????????????????????????????????????",
             "001?????????????????????????????????????????????????????????????",
             "0001????????????????????????????????????????????????????????????",
             "00001???????????????????????????????????????????????????????????",
             "000001??????????????????????????????????????????????????????????",
             "0000001?????????????????????????????????????????????????????????",
             "00000001????????????????????????????????????????????????????????",
             "000000001???????????????????????????????????????????????????????",
             "0000000001??????????????????????????????????????????????????????",
             "00000000001?????????????????????????????????????????????????????",
             "000000000001????????????????????????????????????????????????????",
             "0000000000001???????????????????????????????????????????????????",
             "00000000000001??????????????????????????????????????????????????",
             "000000000000001?????????????????????????????????????????????????",
             "0000000000000001????????????????????????????????????????????????",
             "00000000000000001???????????????????????????????????????????????",
             "000000000000000001??????????????????????????????????????????????",
             "0000000000000000001?????????????????????????????????????????????",
             "00000000000000000001????????????????????????????????????????????",
             "000000000000000000001???????????????????????????????????????????",
             "0000000000000000000001??????????????????????????????????????????",
             "00000000000000000000001?????????????????????????????????????????",
             "000000000000000000000001????????????????????????????????????????",
             "0000000000000000000000001???????????????????????????????????????",
             "00000000000000000000000001??????????????????????????????????????",
             "000000000000000000000000001?????????????????????????????????????",
             "0000000000000000000000000001????????????????????????????????????",
             "00000000000000000000000000001???????????????????????????????????",
             "000000000000000000000000000001??????????????????????????????????",
             "0000000000000000000000000000001?????????????????????????????????",
             "00000000000000000000000000000001????????????????????????????????",
             "000000000000000000000000000000001???????????????????????????????",
             "0000000000000000000000000000000001??????????????????????????????",
             "00000000000000000000000000000000001?????????????????????????????",
             "000000000000000000000000000000000001????????????????????????????",
             "0000000000000000000000000000000000001???????????????????????????",
             "00000000000000000000000000000000000001??????????????????????????",
             "000000000000000000000000000000000000001?????????????????????????",
             "0000000000000000000000000000000000000001????????????????????????",
             "00000000000000000000000000000000000000001???????????????????????",
             "000000000000000000000000000000000000000001??????????????????????",
             "0000000000000000000000000000000000000000001?????????????????????",
             "00000000000000000000000000000000000000000001????????????????????",
             "000000000000000000000000000000000000000000001???????????????????",
             "0000000000000000000000000000000000000000000001??????????????????",
             "00000000000000000000000000000000000000000000001?????????????????",
             "000000000000000000000000000000000000000000000001????????????????",
             "0000000000000000000000000000000000000000000000001???????????????",
             "00000000000000000000000000000000000000000000000001??????????????",
             "000000000000000000000000000000000000000000000000001?????????????",
             "0000000000000000000000000000000000000000000000000001????????????",
             "00000000000000000000000000000000000000000000000000001???????????",
             "000000000000000000000000000000000000000000000000000001??????????",
             "0000000000000000000000000000000000000000000000000000001?????????",
             "00000000000000000000000000000000000000000000000000000001????????",
             "000000000000000000000000000000000000000000000000000000001???????",
             "0000000000000000000000000000000000000000000000000000000001??????",
             "00000000000000000000000000000000000000000000000000000000001?????",
             "000000000000000000000000000000000000000000000000000000000001????",
             "0000000000000000000000000000000000000000000000000000000000001???",
             "00000000000000000000000000000000000000000000000000000000000001??",
             "000000000000000000000000000000000000000000000000000000000000001?",
             "0000000000000000000000000000000000000000000000000000000000000001",
             "0000000000000000000000000000000000000000000000000000000000000000"},
            64);
}

TEST_CASE("Case Dag Large List 2") {
    testDag(
        {
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01111111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011111111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01111111111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011111111111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111111111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx01111111111111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxx011111111111111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxxx0111111111111111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxxx01111111111111111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxxx011111111111111111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxxx0111111111111111111111111111",
            "xxxxxxxxxxxxxxxxxxxxxxx01111111111111111111111111111",
            "xxxxxxxxxxxxxxxxxxxxxx011111111111111111111111111111",
            "xxxxxxxxxxxxxxxxxxxxx0111111111111111111111111111111",
            "xxxxxxxxxxxxxxxxxxxx01111111111111111111111111111111",
            "xxxxxxxxxxxxxxxxxxx011111111111111111111111111111111",
            "xxxxxxxxxxxxxxxxxx0111111111111111111111111111111111",
            "xxxxxxxxxxxxxxxxx01111111111111111111111111111111111",
            "xxxxxxxxxxxxxxxx011111111111111111111111111111111111",
            "xxxxxxxxxxxxxxx0111111111111111111111111111111111111",
            "xxxxxxxxxxxxxx01111111111111111111111111111111111111",
            "xxxxxxxxxxxxx011111111111111111111111111111111111111",
            "xxxxxxxxxxxx0111111111111111111111111111111111111111",
            "xxxxxxxxxxx01111111111111111111111111111111111111111",
            "xxxxxxxxxx011111111111111111111111111111111111111111",
            "xxxxxxxxx0111111111111111111111111111111111111111111",
            "xxxxxxxx01111111111111111111111111111111111111111111",
            "xxxxxxx011111111111111111111111111111111111111111111",
            "xxxxxx0111111111111111111111111111111111111111111111",
            "xxxxx01111111111111111111111111111111111111111111111",
            "xxxx011111111111111111111111111111111111111111111111",
            "xxx0111111111111111111111111111111111111111111111111",
            "xx01111111111111111111111111111111111111111111111111",
            "x011111111111111111111111111111111111111111111111111",
            "0111111111111111111111111111111111111111111111111111",
        },
        52, {}, "1111111111111111111111111111111111111111111111111111", {}, true);
}

TEST_CASE("Case Dag Hard Variant") {
    testDag(
        {
            "????0???????1?1?????", "????1???0???0???????", "?0??????0???0???????",
            "???????????????0?11?", "????10???????1??????", "???1??0???1?????????",
            "?????????????10???1?", "??0???????????????01", "????????0?0????????0",
            "?1???0???0??????????", "??1??0??????1???????", "???????01?1?????????",
            "??????1?0?????????0?", "???????????1????0??0", "???1???????????00???",
            "????0?0????????????1", "???0?????01?????????", "0???1???1???????????",
            "0???????????????1?1?", "00???0??????????????", "??????????????1?1?0?",
            "?????????????01??1??", "??????????????00??1?", "?????1????????00????",
            "??0?1??????????????0", "?????????0?????1???1", "?????00?????????1???",
            "?1????1????????0????", "????1???????1????0??", "???????????11???0???",
            "?????0?????0?0??????", "?0??????0????1??????", "??1??????????0??0???",
            "0????0???????????1??", "???????0?????1???0??", "??0???1???????????0?",
            "????0????????????0?0", "???????????1??1????1", "??1?1?????????1?????",
            "?????0?????????1?0??", "????1??1?????????0??", "???1?1????????0?????",
            "??11?1??????????????", "????????1?00????????", "????1???1??1????????",
            "???1???0?????????1??", "1??????0???????1????", "1?1???0?????????????",
            "???0????0?????1?????", "??0?0????0??????????", "???????????0???0??0?",
            "??0????????1???0????", "???1?0???????????0??", "??0?1?0?????????????",
            "0???0?????????1?????", "????????11?????0????", "????1???0???????1???",
            "?0?1?????1??????????", "????????1?0????1????", "1?????0???????0?????",
            "??1????0???????????0", "??1?????1???????1???", "?????1??1?0?????????",
            "???????1???????1??1?", "?10????1????????????", "????0?????????1??1??",
            "11?????????????1????", "????????0?0??????0??", "????1?1????0????????",
            "?????????0??0??????1", "1?????????1????????0", "?1??????????0?????1?",
            "??0???????????1?1???", "?0?1????????1???????", "????1??????1??????0?",
            "????0?1????0????????", "?1?0??????????????1?", "????0????1???0??????",
            "0????0?????0????????", "??????????0??????0?1", "???1?????????1?1????",
            "????1????0?1????????", "??1??0???1??????????", "??0?1?????????0?????",
            "0??????????10???????", "???????00??????????1", "?????0???0???????1??",
            "???????????1???1?0??", "?0???????????01?????", "??1??????1????????1?",
            "????????????1?1????1", "????????????????????", "????????????????????",
        },
        20, {}, {}, {}, false, true);
}

TEST_CASE("Inferred latches with 4-state case statements") {
    auto& code = R"(
module m;
    logic [2:0] a;
    logic b;
    int c, d, e;

    always_comb begin
        case (b)
            0: c = 1;
            1: c = 1;
            1'bx: c = 1;
            1'bz: c = 1;
        endcase
    end

    always_comb begin
        casez (a)
            3'b000: d = 1;
            3'b001: d = 1;
            3'b01?: d = 1;
            3'b0x?: d = 1;
            3'b0z?: d = 1;
            3'b1??: d = 1;
            3'bx??: d = 1;
            3'bz??: d = 1;
        endcase
    end

    always_comb begin
        unique case (b)
            1'b0: e = 1;
            1'b1: e = 1;
        endcase
    end
endmodule
)";

    AnalysisOptions options;
    options.flags = AnalysisFlags::FullCaseFourState | AnalysisFlags::FullCaseUniquePriority;

    Compilation compilation;
    AnalysisManager analysisManager(options);

    auto [diags, design] = analyze(code, compilation, analysisManager);
    REQUIRE(diags.size() == 6);
    CHECK(diags[0].code == diag::CaseNotWildcard);
    CHECK(diags[1].code == diag::CaseNotWildcard);
    CHECK(diags[2].code == diag::CaseZWithX);
    CHECK(diags[3].code == diag::CaseUnreachable);
    CHECK(diags[4].code == diag::CaseZWithX);
    CHECK(diags[5].code == diag::CaseUnreachable);
}

TEST_CASE("Inferred latches with 2-state case statements") {
    auto& code = R"(
module m;
    logic [2:0] a;
    logic b;
    int c, d, e, f, g;
    logic signed [1:0] h;

    always_comb begin
        case (b)
            1'b0: c = 1;
            1'b1: c = 1;
        endcase
    end

    always_comb begin
        casex (a)
            3'b000: d = 1;
            3'b001: d = 1;
            3'b01?: d = 1;
            3'b1??: d = 1;
        endcase
    end

    always_comb begin
        casex (a)
            3'b000: e = 1;
            3'b001: e = 1;
            3'b010: e = 1;
            3'b1??: e = 1;
        endcase
    end

    always_comb begin
        case (b)
            0: f = 1;
        endcase

        case (h)
            -2: g = 1;
            -1: g = 1;
            0:  g = 1;
            1:  g = 1;
        endcase
    end
endmodule
)";

    Compilation compilation;
    AnalysisManager analysisManager;

    auto [diags, design] = analyze(code, compilation, analysisManager);
    REQUIRE(diags.size() == 2);
    CHECK(diags[0].code == diag::InferredLatch);
    CHECK(diags[1].code == diag::InferredLatch);
}

TEST_CASE("DFA for constant case statements") {
    auto& code = R"(
module m;
    parameter p = 2;
    int i, j;
    logic l;
    always_comb begin
        case (p)
            0: begin end
            1: begin end
            2: i = 1;
            default:;
        endcase

        case (l)
            0: j = 1;
            1: j = 2;
            default:;
        endcase
    end
endmodule
)";

    Compilation compilation;
    AnalysisManager analysisManager;

    auto [diags, design] = analyze(code, compilation, analysisManager);
    CHECK_DIAGS_EMPTY;
}

TEST_CASE("Case statement missing enum values") {
    auto& code = R"(
module m;
    enum {A,B,C,D,E} e;
    initial begin
        case (e)
            A, B, C, D:;
            default;
        endcase
        case (e)
            A, B, C:;
            default;
        endcase
        case (e)
            A, B:;
            default;
        endcase
        case (e)
            A:;
            default;
        endcase

        case (e)
            A, B, C, D:;
        endcase
        case (e)
            A, B, C:;
        endcase
        case (e)
            A, B:;
        endcase
        case (e)
            A:;
        endcase
    end
endmodule
)";

    Compilation compilation;
    AnalysisManager analysisManager;

    auto [diags, design] = analyze(code, compilation, analysisManager);
    REQUIRE(diags.size() == 8);
    CHECK(diags[0].code == diag::CaseEnumExplicit);
    CHECK(diags[1].code == diag::CaseEnumExplicit);
    CHECK(diags[2].code == diag::CaseEnumExplicit);
    CHECK(diags[3].code == diag::CaseEnumExplicit);
    CHECK(diags[4].code == diag::CaseEnum);
    CHECK(diags[5].code == diag::CaseEnum);
    CHECK(diags[6].code == diag::CaseEnum);
    CHECK(diags[7].code == diag::CaseEnum);
}

TEST_CASE("Case statement dups") {
    auto& code = R"(
module m;
    int i;
    event e;
    initial begin
        case (i)
            1, 2:;
            3, 1:;
            default;
        endcase
        case (e)
            null:;
            null:;
            default;
        endcase
    end
endmodule
)";

    Compilation compilation;
    AnalysisManager analysisManager;

    auto [diags, design] = analyze(code, compilation, analysisManager);
    REQUIRE(diags.size() == 2);
    CHECK(diags[0].code == diag::CaseDup);
    CHECK(diags[1].code == diag::CaseDup);
}

TEST_CASE("Case statement overlap") {
    auto& code = R"(
module m;
    logic [65:0] a;
    initial begin
        casex (a)
            65'bx1011z:;
            65'b10111:;
            65'b11011:;
            65'b1101x:;
            65'b110?1:;
            default;
        endcase
        casez (a)
            65'bx1111:;
            65'b1x111:;
            65'b1?111:;
            65'b?1111:;
            65'b?0111:;
            default;
        endcase
    end
endmodule
)";

    Compilation compilation;
    AnalysisManager analysisManager;

    auto [diags, design] = analyze(code, compilation, analysisManager);
    REQUIRE(diags.size() == 7);
    CHECK(diags[0].code == diag::CaseUnreachable);
    CHECK(diags[1].code == diag::CaseOverlap);
    CHECK(diags[2].code == diag::CaseOverlap);
    CHECK(diags[3].code == diag::CaseZWithX);
    CHECK(diags[4].code == diag::CaseZWithX);
    CHECK(diags[5].code == diag::CaseOverlap);
    CHECK(diags[6].code == diag::CaseOverlap);
}

TEST_CASE("Case statement with huge bit width selector") {
    auto& code = R"(
module test9(
  input reg [100:0] sel_i,
  input reg trg_i,
  output reg [1:0] reg_o
);
  always @(posedge trg_i) begin
    // Negating the literal with unknowns makes it all unknowns, i.e. all wildcards
    casex (sel_i)
      -12'b00zzzzz00001,
      12'b11: reg_o = 2'b01;
    endcase
  end
endmodule

module test10(
  input reg [100:0] sel_i,
  input reg trg_i,
  output reg [1:0] reg_o
);
  always @(posedge trg_i) begin
    casex (sel_i)
      12'sb00xxxxx00001,
      -12'b00zzzzz00001,
      12'b11: reg_o = 2'b01;
    endcase
  end
endmodule
)";

    Compilation compilation;
    AnalysisManager analysisManager;

    auto [diags, design] = analyze(code, compilation, analysisManager);
    REQUIRE(diags.size() == 3);
    CHECK(diags[0].code == diag::CaseUnreachable);
    CHECK(diags[1].code == diag::CaseOverlap);
    CHECK(diags[2].code == diag::CaseUnreachable);
}

TEST_CASE("Case items with unknowns that are not wildcards") {
    auto& code = R"(
module m;
    logic [3:0] a;
    initial begin
        case (a)
            4'b?10:;
            4'bx10:;
            default;
        endcase
        casez (a)
            4'bx10:;
            default;
        endcase
    end
endmodule
)";

    Compilation compilation;
    AnalysisManager analysisManager;

    auto [diags, design] = analyze(code, compilation, analysisManager);
    REQUIRE(diags.size() == 3);
    CHECK(diags[0].code == diag::CaseNotWildcard);
    CHECK(diags[1].code == diag::CaseNotWildcard);
    CHECK(diags[2].code == diag::CaseZWithX);
}

TEST_CASE("Case too complex") {
    auto& code = R"(
module m;
    logic [51:0] a;
    always_comb begin
        casex (a)
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111111:;
            52'bxxxxxxxxxxxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxx01111111x11:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011111111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01x11111111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx011111111111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111111111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01111111111111111:;
            52'bxxxxxxxxxxxxxxxxx0xxxxxxxxxxxxxxxx0111111111111x1111:;
            52'bxxxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxx0111111111111111111:;
            52'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01111111111111111111:;
            52'bxxxxxx1xxxxxxxxxxxxx1xxxxxx1xxx011111111111111111111:;
            52'bxxxxxxxxxxxx0xxxxxxxxxxxxxxxxx0111111111111111111111:;
        endcase
    end
endmodule
)";

    AnalysisOptions options;
    options.maxCaseAnalysisSteps = 1024;

    Compilation compilation;
    AnalysisManager analysisManager(options);

    auto [diags, design] = analyze(code, compilation, analysisManager);
    REQUIRE(diags.size() == 1);
    CHECK(diags[0].code == diag::CaseComplex);
}
